mod upper_computer;

use upper_computer::{DataProcessor, DataProcessorConfig, ProcessResult, DataFrame};
use tokio::sync::mpsc;
use tokio::signal;
use std::time::Duration;

// 定义发给客户端的消息类型
#[derive(Debug)]
enum ClientMessage {
    ProcessedData(DataFrame),  // 处理后的完整数据帧
    Error(String),             // 错误信息
    Status(String),            // 状态信息
}

#[tokio::main]
async fn main() {
    // 创建结果接收通道（处理器 -> 主程序）
    let (processor_sender, mut processor_receiver) = mpsc::channel(100);
    
    // 创建客户端发送通道（主程序 -> 客户端发送任务）
    let (client_sender, mut client_receiver) = mpsc::channel(100);
    // 克隆发送端，用于主程序中发送消息
    let main_client_sender = client_sender.clone();
    
    // 创建处理器配置
    let config = DataProcessorConfig {
        frame_header: 0xAA,
        frame_footer: 0x55,
        enable_checksum: false,
        ..DataProcessorConfig::default()
    };
    
    // 创建数据处理器
    let mut processor = DataProcessor::new(config.clone(), processor_sender);
    
    // 1. 结果处理与客户端发送任务
    tokio::spawn(async move {
        println!("客户端发送服务已启动");
        
        // 模拟客户端连接
        let mut client_connected = true;
        
        // 处理来自处理器的结果并发送给客户端
        while let Some(result) = processor_receiver.recv().await {
            if !client_connected {
                eprintln!("客户端已断开连接，无法发送数据");
                continue;
            }
            
            // 根据处理结果生成要发送给客户端的消息
            let client_msg = match result {
                ProcessResult::Success(frame) => {
                    ClientMessage::ProcessedData(frame.clone())
                }
                ProcessResult::ParseError(msg) => {
                    ClientMessage::Error(format!("解析错误: {}", msg))
                }
                ProcessResult::ChecksumError { calculated, received } => {
                    ClientMessage::Error(format!(
                        "校验和错误: 计算值=0x{:X}, 接收值=0x{:X}", 
                        calculated, received
                    ))
                }
                ProcessResult::UnsupportedCommand(cmd) => {
                    ClientMessage::Error(format!("不支持的命令: 0x{:X}", cmd))
                }
            };
            
            // 发送给客户端
            if let Err(e) = client_sender.send(client_msg).await {
                eprintln!("发送给客户端失败: {}", e);
                client_connected = false;
            }
        }
    });
    
    // 2. 客户端消息接收与处理任务
    tokio::spawn(async move {
        while let Some(msg) = client_receiver.recv().await {
            // 模拟将消息发送给客户端
            match msg {
                ClientMessage::ProcessedData(frame) => {
                    println!("\n===== 发送给客户端 =====");
                    println!("设备地址: 0x{:X}", frame.device_addr);
                    println!("命令码: 0x{:X}", frame.cmd);
                    println!("数据内容: {:?}", frame.data);
                    println!("时间戳: {}", frame.timestamp);
                    println!("=======================");
                }
                ClientMessage::Error(err) => {
                    println!("\n===== 发送给客户端错误 =====");
                    println!("{}", err);
                    println!("==========================");
                }
                ClientMessage::Status(status) => {
                    println!("\n===== 客户端状态通知 =====");
                    println!("{}", status);
                    println!("==========================");
                }
            }
        }
    });
    
    // 3. 模拟数据接收任务
    tokio::spawn(async move {
        let mut counter = 0;
        loop {
            tokio::time::sleep(Duration::from_secs(3)).await;
            
            // 生成模拟数据帧
            let test_data = [
                0xAA, 0x01, 0x01, 0x04, 
                (counter & 0xFF) as u8, 
                ((counter + 1) & 0xFF) as u8, 
                ((counter + 2) & 0xFF) as u8, 
                ((counter + 3) & 0xFF) as u8, 
                0x0A, 0x55
            ];
            
            println!("\n收到下位机数据: {:X?}", test_data);
            processor.process_raw_data(&test_data).await;
            
            counter += 4;
        }
    });
    
    // 4. 发送初始状态给客户端（使用克隆的发送端）
    let _ = main_client_sender.send(ClientMessage::Status(
        "上位机已启动，等待接收数据...".to_string()
    )).await;
    
    println!("上位机程序已启动，正在运行中...");
    println!("按 Ctrl+C 退出程序");
    
    // 等待中断信号
    signal::ctrl_c().await.expect("无法捕获中断信号");
    println!("\n收到退出信号，正在关闭程序...");
    let _ = main_client_sender.send(ClientMessage::Status(
        "上位机即将关闭".to_string()
    )).await;
    println!("程序已安全退出");
}
    